package com.fast.develop.dm.meta.loader;

import com.fast.develop.dm.meta.MetaField;
import com.fast.develop.dm.meta.builder.MetaFieldBuilder;
import com.fast.develop.dm.meta.field.FieldCatelog;
import com.fast.develop.dm.meta.value.ValueGeneration;
import com.fast.develop.dm.meta.value.ValueValidation;
import com.fast.develop.dm.meta.factory.TypeFactory;
import com.fast.develop.dm.meta.factory.ValueGenerationFactory;
import com.fast.develop.dm.meta.factory.ValueValidationFactory;
import org.json.JSONArray;
import org.json.JSONObject;

import java.util.*;

/**
 * @author 莫寅
 * @createTime 2022-06-04 13:31
 * @desc：
 */
public class MetaFieldLoader {


    public MetaField load(JSONObject rawSchema){
        MetaFieldBuilder metaFieldBuilder = new MetaFieldBuilder();

        bindName(rawSchema, metaFieldBuilder);
        bindType(rawSchema, metaFieldBuilder);
        bindColumnName(rawSchema, metaFieldBuilder);
        bindComment(rawSchema, metaFieldBuilder);
        bindLength(rawSchema, metaFieldBuilder);
        bindDecimalLength(rawSchema, metaFieldBuilder);
        bindRequired(rawSchema, metaFieldBuilder);
        bindPrimaryKey(rawSchema, metaFieldBuilder);
        bindCanExcel(rawSchema, metaFieldBuilder);
        bindApiHide(rawSchema, metaFieldBuilder);
        bindUnique(rawSchema, metaFieldBuilder);
        bindValueGenerationStrategy(rawSchema, metaFieldBuilder);
        bindValueValidations(rawSchema, metaFieldBuilder);

        MetaField metaField = new MetaField(metaFieldBuilder);
        return metaField;
    }


    private void bindName(JSONObject rawSchema, MetaFieldBuilder metaFieldBuilder){
        metaFieldBuilder.setName(rawSchema.optString("name"));
    }
    private void bindColumnName(JSONObject rawSchema, MetaFieldBuilder metaFieldBuilder){
        metaFieldBuilder.setColumnName(rawSchema.optString("columnName"));
    }
    private void bindComment(JSONObject rawSchema, MetaFieldBuilder metaFieldBuilder){
        metaFieldBuilder.setComment(rawSchema.optString("comment"));
    }
    private void bindType(JSONObject rawSchema, MetaFieldBuilder metaFieldBuilder){
        String catalog = rawSchema.optString("catalog");
        FieldCatelog fieldType = TypeFactory.create(catalog, rawSchema, metaFieldBuilder);
        metaFieldBuilder.setType(fieldType);
    }
    private void bindLength(JSONObject rawSchema, MetaFieldBuilder metaFieldBuilder){
        metaFieldBuilder.setLength(rawSchema.optInt("length"));
    }
    private void bindDecimalLength(JSONObject rawSchema, MetaFieldBuilder metaFieldBuilder){
        metaFieldBuilder.setDecimalLength(rawSchema.optInt("decimalLength"));
    }
    private void bindRequired(JSONObject rawSchema, MetaFieldBuilder metaFieldBuilder){
        metaFieldBuilder.setRequired(rawSchema.optBoolean("required"));
    }
    private void bindPrimaryKey(JSONObject rawSchema, MetaFieldBuilder metaFieldBuilder){
        metaFieldBuilder.setPrimaryKey(rawSchema.optBoolean("primaryKey"));
    }
    private void bindCanExcel(JSONObject rawSchema, MetaFieldBuilder metaFieldBuilder){
        metaFieldBuilder.setCanExcel(rawSchema.optBoolean("canExcel"));
    }
    private void bindApiHide(JSONObject rawSchema, MetaFieldBuilder metaFieldBuilder){
        metaFieldBuilder.setApiHide(rawSchema.optBoolean("apiHide"));
    }
    private void bindUnique(JSONObject rawSchema, MetaFieldBuilder metaFieldBuilder){
        metaFieldBuilder.setUnique(rawSchema.optBoolean("unique"));
    }

    private void bindValueGenerationStrategy(JSONObject rawSchema, MetaFieldBuilder metaFieldBuilder){
        JSONObject value = rawSchema.optJSONObject("valueGenerationStrategy");
        if(Objects.nonNull(value)){
            String type = value.optString("type");
            ValueGeneration valueGeneration = ValueGenerationFactory.create(type, value, metaFieldBuilder);
            metaFieldBuilder.setValueGenerationStrategy(valueGeneration);
        }
    }

    private void bindValueValidations(JSONObject rawSchema, MetaFieldBuilder metaFieldBuilder){
        JSONArray value = rawSchema.optJSONArray("valueValidations");

        if(Objects.nonNull(value)){
            List<ValueValidation> valueValidations = new ArrayList();

            value.forEach(o -> {
                JSONObject jsonObject = (JSONObject)o;
                String type = jsonObject.optString("type");
                if(Objects.nonNull(value)){
                    ValueValidation valueGeneration = ValueValidationFactory.create(type, jsonObject, metaFieldBuilder);
                    valueValidations.add(valueGeneration);
                }
            });

            metaFieldBuilder.setValueValidations(valueValidations);
        }
    }




}
